// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using InterpriseSuiteEcommerceCommon.Extensions;
using System.Runtime.Serialization;

namespace InterpriseSuiteEcommerceCommon.DTO
{
    [DataContractAttribute]
    public class AttributeData
    {
        [DataMemberAttribute]
        public string Code = string.Empty;

        [DataMemberAttribute]
        public string Value = string.Empty;

        public AttributeData() { }

        public AttributeData(string code, string value)
        {
            this.Code = code;
            this.Value = value;
        }

        public static AttributeData New(string code, string value)
        {
            return new AttributeData(code, value);
        }
    }

    [DataContractAttribute]
    public class MatrixItemData
    {
        public MatrixItemData(int counter, string itemCode)
        {
            this.Counter = counter;
            this.ItemCode = itemCode;
        }

        [DataMemberAttribute]
        public int Counter;

        [DataMemberAttribute]
        public string ItemCode;

        [DataMemberAttribute]
        public string AltText { get; set; }

        [DataMemberAttribute]
        public string Title { get; set; }

        [DataMemberAttribute]
        public List<AttributeData> Attributes = new List<AttributeData>();

        [DataMemberAttribute]
        public ProductImageData ImageData = null;

        #region GetMatrixItems

        public static List<MatrixItemData> GetMatrixItems(int itemCounter, string itemCode, bool loadImageData)
        {
            var matrixItems = new List<MatrixItemData>();
            var list = new List<System.Collections.Generic.KeyValuePair<int, string>>();

            // register the individual items..
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "exec eCommerceGetMatrixItemAttributes @ItemCode = {0}, @WebsiteCode = {1}, @CurrentDate = {2}, @LanguageCode = {3}, @ContactCode = {4}"
                    , DB.SQuote(itemCode), DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode), DB.SQuote(Localization.DateTimeStringForDB(DateTime.Now)), DB.SQuote(Customer.Current.LanguageCode), DB.SQuote(Customer.Current.ContactCode)))
                {
                    while (reader.Read())
                    {
                        int counter = DB.RSFieldInt(reader, "Counter");
                        string matrixItemCode = DB.RSField(reader, "MatrixItemCode");

                        //generate the listItems
                        list.Add(new KeyValuePair<int, string>(counter, matrixItemCode));

                        var item = new MatrixItemData(counter, matrixItemCode);

                        for (int ordinal = 1; ordinal <= 6; ordinal++)
                        {
                            string attributeCode = DB.RSField(reader, string.Format("AttributeCode{0}", ordinal));
                            string attributeValue = DB.RSField(reader, string.Format("Attribute{0}", ordinal));

                            if (CommonLogic.IsStringNullOrEmpty(attributeCode)) continue;
                            // NOTE:
                            //  Since the code and values here are used as hashtable via JSON
                            //  We must make sure that the attribute code is a valid JSON name
                            //  and the attribute value is a valid javascript string
                            //  We will then MATCH how we encode these values to the attributes of per matrix item..
                            item.Attributes.Add(AttributeData.New(Security.JavascriptEscapeClean(attributeCode), attributeValue.ToUrlEncode()));
                        }

                        matrixItems.Add(item);
                    }
                }
            }

            if (loadImageData)
            {
                matrixItems = GetProductImageDataList(matrixItems, itemCounter, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM);
            }

            return matrixItems;
        }

        public static List<MatrixItemData> GetProductImageDataList(List<MatrixItemData> matrixItemDataList, int matrixGroupCounter, string itemType)
        {
            var imageFileNameData = GetImageNameData(matrixItemDataList);
            bool watermarkEnabled = AppLogic.AppConfigBool("Watermark.Enabled");

            string websiteCode = DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode);

            foreach (var matrixItemDataItem in matrixItemDataList)
            {
                bool exists = false;
                string fileName = String.Empty;
                string itemCode = String.Empty;

                matrixItemDataItem.ImageData = new ProductImageData(matrixItemDataItem.Counter, matrixItemDataItem.ItemCode);
                //-------------------------------- icon ---------------------------------
                ImageSizeTypes type = ImageSizeTypes.icon;
                var imageItem = imageFileNameData.IconList.FirstOrDefault(i => i.ItemCode == matrixItemDataItem.ItemCode);
                if(imageItem != null) 
                { 
                    fileName = imageItem.Filename; 
                    exists = true;
                }

                string url = AppLogic.LocateImageFilenameUrl(DomainConstants.EntityProduct, matrixItemDataItem.ItemCode, type.ToString(), fileName, watermarkEnabled, out exists);  
                var productImageData = new ProductImageData(matrixItemDataItem.Counter, matrixItemDataItem.ItemCode);
                var productImage = new ProductImage(url, url) { exists = exists, ImageSizeType = type };
                matrixItemDataItem.ImageData.icon = productImage;

                //-------------------------------- medium ---------------------------------
                type = ImageSizeTypes.medium;
                imageItem = imageFileNameData.MediumList.FirstOrDefault(i => i.ItemCode == matrixItemDataItem.ItemCode);
                if(imageItem != null)
                {
                    fileName = imageItem.Filename; 
                    exists = true;
                }

                url = AppLogic.LocateImageFilenameUrl(DomainConstants.EntityProduct, matrixItemDataItem.ItemCode, type.ToString(), fileName, watermarkEnabled, out exists);
                productImageData = new ProductImageData(matrixItemDataItem.Counter, matrixItemDataItem.ItemCode);
                productImage = new ProductImage(url, url) { exists = exists, ImageSizeType = type };
                matrixItemDataItem.ImageData.medium = productImage;

                //-------------------------------- large ---------------------------------
                type = ImageSizeTypes.large;
                imageItem = imageFileNameData.LargeList.FirstOrDefault(i => i.ItemCode == matrixItemDataItem.ItemCode);
                if (imageItem != null)
                {
                    fileName = imageItem.Filename;
                    exists = true;
                }

                url = AppLogic.LocateImageFilenameUrl(DomainConstants.EntityProduct, matrixItemDataItem.ItemCode, type.ToString(), fileName, watermarkEnabled, out exists);
                productImageData = new ProductImageData(matrixItemDataItem.Counter, matrixItemDataItem.ItemCode);

                productImage = new ProductImage(url, url) { exists = exists, ImageSizeType = type };
                matrixItemDataItem.ImageData.large = productImage;

                SetImageSize(matrixItemDataItem.ImageData.large);
                //-------------------------------------------------------------------------

                //------------------------- Multi-Images ----------------------------------
                var MultiImageFileName = imageFileNameData.MultiImageList;
                //display medium images, sync micro and large images
                var multiImageItemList = imageFileNameData.MultiImageList.Where(i => i.ItemCode == matrixItemDataItem.ItemCode);
                foreach (var multiImageItemListItem in multiImageItemList)
                {
                    matrixItemDataItem.ImageData.mediumImages.Add(ProductImage.LocateMultiImage("product", itemCode, multiImageItemListItem.Filename, "medium"));
                    matrixItemDataItem.ImageData.microImages.Add(ProductImage.LocateMultiImage("product", itemCode, multiImageItemListItem.Filename, "micro"));
                    ProductImage largeImage = ProductImage.LocateMultiImage("product", itemCode, multiImageItemListItem.Filename, "large");
                    SetImageSize(largeImage);
                    matrixItemDataItem.ImageData.largeImages.Add(largeImage);
                }

                //dispay swatches
                if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM)
                {
                    matrixItemDataItem.ImageData.swatch = ProductImage.Locate("product", matrixGroupCounter, "swatch", matrixItemDataItem.Counter);
                }
            }
            return matrixItemDataList;
        }

        public static void SetImageSize(ProductImage img)
        {
            if (img.exists)
            {
                System.Drawing.Size size = CommonLogic.GetImagePixelSize(img.rel);
                img.size.width = size.Width;
                img.size.height = size.Height;
                img.rel = string.Empty;
            }
        }

        #endregion

        public static ImageNameData GetImageNameData(IEnumerable<MatrixItemData> listItemData)
        {
            string fileName = String.Empty;
            string itemCode = String.Empty;

            var arrCode = String.Join(",", listItemData.Select(d => d.ItemCode.ToDbQuote()).ToArray());
            if (arrCode.IsNullOrEmptyTrimmed())
            {
                arrCode = "''";
            }

            string websiteCodeQuoted = DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode);

            var imageNameData = new ImageNameData();
            string query = "{0};{1};{2}{3}".FormatWith(
                        "SELECT Filename, ItemCode FROM InventoryOverrideImage (NOLOCK) WHERE ItemCode in ({0}) AND IsDefaulticon= 1 AND WebSiteCode = {1}".FormatWith(arrCode, websiteCodeQuoted),
                        "SELECT Filename, ItemCode FROM InventoryOverrideImage (NOLOCK) WHERE ItemCode in ({0}) AND IsDefaultmedium = 1 AND WebSiteCode = {1}".FormatWith(arrCode, websiteCodeQuoted),
                        "SELECT Filename, ItemCode FROM InventoryOverrideImage (NOLOCK) WHERE ItemCode in ({0}) AND WebSiteCode = {1}".FormatWith(arrCode, websiteCodeQuoted), 
                        !AppLogic.AppConfigBool("ImageFileNameOverride.Enabled")?
                        ";SELECT e.Filename, ItemCode FROM InventoryOverrideImage e with (NOLOCK) WHERE e.ItemCode in ({0}) AND WebSiteCode = {1} AND HasMedium = 1 ORDER BY ImageIndex".FormatWith(arrCode, websiteCodeQuoted) : String.Empty
                        );

            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRS(query, con))
                {
                    //process Icon
                    while (reader.Read())
                    {
                        imageNameData.IconList.Add(new ImageNameDataItem() { Filename=DB.RSField(reader, "Filename"), ItemCode = DB.RSField(reader, "ItemCode") });
                    }
                    
                    //Process Medium
                    if (reader.NextResult())
                    {
                        while (reader.Read())
                        {
                            imageNameData.MediumList.Add(new ImageNameDataItem() { Filename = DB.RSField(reader, "Filename"), ItemCode = DB.RSField(reader, "ItemCode") });
                        }
                    }

                    //Process Large
                    if (reader.NextResult())
                    {
                        while (reader.Read())
                        {
                            imageNameData.LargeList.Add(new ImageNameDataItem() { Filename = DB.RSField(reader, "Filename"), ItemCode = DB.RSField(reader, "ItemCode") });
                        }
                    }

                    //Process MultiImageFileName
                    if (reader.NextResult())
                    {
                        while (reader.Read())
                        {
                            imageNameData.MultiImageList.Add(new ImageNameDataItem() { Filename = DB.RSField(reader, "Filename"), ItemCode = DB.RSField(reader, "ItemCode") });
                        }
                    }

                }

            }

            return imageNameData;

        }
    }

    [DataContractAttribute]
    public class CustomMatrixItem
    {
        [DataMemberAttribute]
        public int MatrixCounter { get; set; }

        [DataMemberAttribute]
        public string MatrixCode { get; set; }
    }

}



